package com.example.benyq.mediaplayerdemo;

import android.Manifest;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;

import com.example.benyq.mediaplayerdemo.recyclerview.BenyqBaseAdapter;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity implements IPlayback.Callback {

    private AppCompatImageView mIvPlayLast;
    private AppCompatImageView mIvPlayToggle;
    private AppCompatImageView mIvPlayNext;
    private PlayerService mPlayerService;
    private TextView mIvProgress;
    private TextView mIvDuration;
    private RecyclerView mRvMusic;
    private MusicAdapter mMusicAdapter;
    private List<Music> mMusicList = new ArrayList<>();

    private SeekBar mSeekBar;
    private String song;
    private int index = -1;
    private int musicCount = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindPlaybackService();
        initView();
        initEvent();
        song = "http://img.owspace.com/F_vne408361_1512551681.4364588.mp3";
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
                PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }else {
            queryMusic();
        }
        FileDirUtils.getAddress(this);

        if (savedInstanceState != null){
            index = savedInstanceState.getInt("musicIndex");
            playTimer();
            if (mPlayerService != null){
                if (mPlayerService.isPlaying()){
                    mIvPlayToggle.setImageResource(R.drawable.ic_play);
                }else {
                    mIvPlayToggle.setImageResource(R.drawable.ic_pause);
                }
            }

        }

    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("musicIndex", index);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unRegister();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1){
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                queryMusic();
            }
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mPlayerService = ((PlayerService.LocalBinder) iBinder).getService();
            register();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            unRegister();
        }
    };

    private void initView() {
        mIvPlayLast = findViewById(R.id.button_play_last);
        mIvPlayToggle = findViewById(R.id.button_play_toggle);
        mIvPlayNext = findViewById(R.id.button_play_next);
        mIvProgress = findViewById(R.id.text_view_progress);
        mIvDuration = findViewById(R.id.text_view_duration);
        mSeekBar = findViewById(R.id.seek_bar);
        mRvMusic = findViewById(R.id.rv_music);
        mRvMusic.setLayoutManager(new LinearLayoutManager(this));
        mMusicAdapter = new MusicAdapter(this, mMusicList, R.layout.item_music);
        mMusicAdapter.setOnItemClickListener(new BenyqBaseAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(View view, int position) {
                cancelTimer();
                index = position;
                mPlayerService.play(mMusicList.get(position).path);
            }

            @Override
            public void onItemLongClick(View view, int position) {

            }
        });
        mRvMusic.setAdapter(mMusicAdapter);

    }

    private void initEvent() {
        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                cancelTimer();
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mPlayerService.seekTo(getSeekDuration(seekBar.getProgress()));
                playTimer();
            }
        });

        mIvPlayToggle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mPlayerService == null) {
                    return;
                }
                if (mPlayerService.isPlaying()) {
                    mPlayerService.pause();
                    mIvPlayToggle.setImageResource(R.drawable.ic_play);
                } else {
                    mPlayerService.play(song);
                    playTimer();
                    mIvPlayToggle.setImageResource(R.drawable.ic_pause);
                }
            }
        });

        mIvPlayNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playNextMusic();
            }
        });

        mIvPlayLast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playLastMusic();
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });

    }

    private void playNextMusic() {
        cancelTimer();
        index ++;
        if (index == musicCount){
            index = 0;
        }
        mPlayerService.play(mMusicList.get(index).path);
        playTimer();
    }

    private void playLastMusic() {
        cancelTimer();
        index --;
        if (index < 0){
            index = musicCount - 1;
        }
        mPlayerService.play(mMusicList.get(index).path);
        playTimer();
    }


    private void register() {
        mPlayerService.registerCallback(this);
    }

    private void unRegister() {
        if (mPlayerService != null) {
            mPlayerService.unregisterCallback(this);
        }
    }

    Timer timer = null;


    private void playTimer() {
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (mPlayerService == null)
                    return;
                if (mPlayerService.isPlaying()) {
                    handleProgress.post(runnable);
                }
            }
        }, 0, 1000);
    }

    private void cancelTimer() {
        if (timer != null) {
            timer.cancel();
        }
        timer = null;
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            if (mPlayerService.isPlaying()) {
                if (isFinishing()) {
                    return;
                }
                Log.e("getSeekDuration", "run: " + mPlayerService.getProgress());
                int progress = (int) (mSeekBar.getMax()
                        * ((float) mPlayerService.getProgress() / (float) mPlayerService.getDuration()));
                updateProgressTextWithProgress(mPlayerService.getProgress());
                updateDuration();
                if (progress >= 0 && progress <= mSeekBar.getMax()) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        mSeekBar.setProgress(progress, true);
                    } else {
                        mSeekBar.setProgress(progress);
                    }
                }
            }
        }
    };

    private int getSeekDuration(int progress) {
        return (int) (getCurrentSongDuration() * ((float) progress / mSeekBar.getMax()));
    }

    private int getCurrentSongDuration() {
        int duration = 0;
        if (mPlayerService != null) {
            duration = mPlayerService.getDuration();
        }
        return duration;
    }

    Handler handleProgress = new Handler();

    private void bindPlaybackService() {
        this.bindService(new Intent(this, PlayerService.class), mConnection, Context.BIND_AUTO_CREATE);
    }

    private void updateProgressTextWithProgress(int progress) {
        mIvProgress.setText(TimeUtils.formatDuration(progress));
    }

    private void updateDuration() {
        mIvDuration.setText(TimeUtils.formatDuration(mPlayerService.getDuration()));
    }


    @Override
    public void onComplete(PlayState state) {

    }

    @Override
    public void onPlayStatusChanged(PlayState state) {
        Log.e("onPlayStatusChanged", "onPlayStatusChanged: "+ state);
        switch (state) {
            case INIT:
                break;
            case PREPARE:
                break;
            case PLAYING:
                updateDuration();
                playTimer();
                mIvPlayToggle.setImageResource(R.drawable.ic_pause);
                break;
            case PAUSE:
                cancelTimer();
                mIvPlayToggle.setImageResource(R.drawable.ic_play);
                break;
            case ERROR:
                break;
            case COMPLETE:
                cancelTimer();
                mIvPlayToggle.setImageResource(R.drawable.ic_play);
                mSeekBar.setProgress(0);
                playNextMusic();
                break;
            case PLAY_NEXT:
                playNextMusic();
                break;
            case PLAY_LAST:
                playLastMusic();
                break;
        }
    }

    @Override
    public void onPosition(int position) {
        Log.e("position", "onPosition.......=" + position);
    }

    private void queryMusic() {
        String[] projection = new String[]{MediaStore.Files.FileColumns._ID,
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Files.FileColumns.SIZE
        };

        //MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
        //Uri.parse("content://media/external/file")
        ContentResolver contentResolver = getContentResolver();
        Cursor cursor = contentResolver.query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                null,
                null,
                null,
                MediaStore.Audio.AudioColumns.IS_MUSIC);

        if (cursor != null && cursor.moveToFirst()) {
            do {
                Music music = new Music();
                music.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
                music.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                music.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                music.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                music.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
                mMusicList.add(music);
                Log.e("queryMusic", music.toString());
            } while (cursor.moveToNext());
            if (mMusicList.size() > 0){
                index = 0;
                musicCount = mMusicList.size();
            }
            mMusicAdapter.notifyDataSetChanged();
            cursor.close();
        }
    }
}
